<?php
// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2023-06-25 20:27:05
// |@----------------------------------------------------------------------
// |@LastEditTime : 2023-12-04 10:34:16
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 
// |@----------------------------------------------------------------------
// |@FilePath     : Folder.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2023 http://www.ladmin.cn   All rights reserved. 
// ------------------------------------------------------------------------
namespace app\setting\logic;

use think\admin\Logic;

/**
 * 文件分类管理类，用于实现文件分类相关的业务逻辑操作。
 */
class Folder extends Logic
{
    /**
     * 根据条件查询文件分类列表。
     * 如果 $data 中包含 name 字段，则返回名称包含指定字符串的文件分类列表；
     * 否则返回全部文件分类列表。文件分类列表按 sort 字段递增排序。
     * @param array $data 查询条件。可以包含 name 字段，表示查询名称包含指定字符串的文件分类列表。
     * @return array 文件分类列表数组。
     */
    public function getList(): array
    {
        // 根据查询条件 $data 组装 SQL 的 WHERE 子句
        $where = $this->app->request->user_info['id'] != "1" ? [['user_id', '0', $this->app->request->user_info['id']]] : [["id", ">", 0]];
        // 查询数据库，获取符合条件的所有文件分类记录
        $menus = $this->modelSystemFolder->where($where)->order(['name' => 'asc'])->field('id, pid, name')->select();
        // 返回查询结果和执行状态信息
        return $this->json(SUCCESS, lang('folder.get_folder_list_success'), $menus->toArray());
    }

    /**
     * 保存文件分类信息。如果 $data 中包含 id，则执行更新操作；否则执行添加操作。
     * @param array $data 文件分类信息。必须包含 name、sort、status 等字段。
     * @return JsonResponse
     */
    public function saveFolder(array $data)
    {
        return $this->tryCatch(function() use ($data) {
            if (!empty($data['id'])) {
                // 如果传入的 $data 中有 id ，则执行更新操作
                $this->modelSystemFolder->updateById($data['id'], $data);
            } else {
                // 否则执行添加操作
                $data['id'] = $this->modelSystemFolder->add($data);
            }
            // 返回保存结果和文件分类信息
            return $this->json(SUCCESS, lang('folder.save_folder_info_success'), $data);
        });
    }

    /**
     * 以事务方式删除多个文件分类及其所有子孙文件分类。
     * @param array $data 待删除文件分类ID列表
     * @return JsonResponse
     * @throws \think\db\exception\PDOException
     * @throws \Throwable
     */
    public function moveFolder(array $data)
    {
        return $this->tryCatch(function() use ($data) {
            if (in_array($data['pid'], $data['ids'])) {
                return $this->json(ERROR, lang('folder.not_move_self'));
            }
            $this->modelSystemFolder->whereIn('id', $data['ids'])->update(['pid' => $data['pid']]);
            $this->modelSystemFile->whereIn('id', $data['ids'])->update(['pid' => $data['pid']]);
            // 返回保存结果和文件分类信息
            return $this->json(SUCCESS, lang('folder.move_files_success'));
        });
    }

    /**
     * 以事务方式删除多个文件分类及其所有子孙文件分类。
     * @param array $data 待删除文件分类ID列表
     * @return JsonResponse
     * @throws \think\db\exception\PDOException
     * @throws \Throwable
     */
    public function deleteFolder(array $data)
    {
        return $this->tryCatch(function() use ($data) {
            // 找到所有待删除的节点和它们的所有子节点。
            $toDelete = $this->modelSystemFolder->whereIn('id', $data['ids'])->select();
            $toDeleteIds = array_column($toDelete->toArray(), 'id');
            foreach ($toDelete->toArray() as $item) {
                $toDeleteIds = array_merge($toDeleteIds, $this->getDescendantIds($this->modelSystemFolder, $item['id']));
            }
            // 先删除所有文件
            $this->modelSystemFile->whereIn('pid', $toDeleteIds)->delete();
            // 删除所有待删除的节点和它们的所有子节点。
            $this->modelSystemFolder->deleteById($toDeleteIds);
            // 返回删除成功的信息和状态
            return $this->json(SUCCESS, lang('folder.delete_folder_success'));
        });
    }
}